
#include "mb_datamodel.h"
#include "mb_adu.h"
#include "mb_debug.h"
#include "mb_functioncode.h"
#include "mb_discreteinputs.h"
#include "mb_comm.h"
#include "mb_crc.h"


/**
 * @brief 02 读离散输入功能码 响应
 * @param hslave        从站指针
 * @param pReqbuf       需要解析的数据指针
 * @param pRspbuf       响应数据指针
 * @param pRspbuflen    响应数据长度
 * @ret   MB_OK 成功 其它 出错
*/
MB_StatusTypeDef MB_DISINPUT_Read_Response(
    MB_SLAVE_HandleTypeDef *hslave, 
    uint8_t *pReqbuf, 
    uint8_t *pRspbuf, 
    uint16_t *pRspbuflen)
{
    uint16_t dstDataLen = 0;
    uint16_t dstBufLen = 0;
    uint16_t crc    = 0;

    MB_READ_REQADU_HandleTypeDef *pReqADU = (MB_READ_REQADU_HandleTypeDef *)pReqbuf;  
    MB_READ_RSPADU_HandleTypeDef *pRspADU = (MB_READ_RSPADU_HandleTypeDef *)pRspbuf;  
    //判断线圈数量是不是 < 2000 (GB/T 1958.2.1 2008  第十三页)
    if(MB_PP_NTOHS(pReqADU->Pdu.Quantity) < 0x7d0 || MB_PP_NTOHS(pReqADU->Pdu.Quantity) == 0) //2000
    {
        //判断开始地址加上长度是不是在定义的寄存器范围内
        if(MB_PP_NTOHS(pReqADU->Pdu.StartAddress) + MB_PP_NTOHS(pReqADU->Pdu.Quantity) < hslave->Regedit.DiscretesInputBufSize)
        {
            //处理请求
            pRspADU->AdditionalAddress = hslave->SlaveID;
            pRspADU->Pdu.FunctionCode  = MB_FUN_READ_DISCRETE_INPUTS;
            //从内存中读取输入
            if(MB_BitArrayToByteArray(
                 pRspADU->Pdu.Data, 
                 MB_PP_NTOHS(pReqADU->Pdu.StartAddress),
                 MB_PP_NTOHS(pReqADU->Pdu.Quantity),
                 hslave->Regedit.pDiscretesInputBuffPtr,
                 &dstDataLen
                 ) == MB_OK)
                 {
                    //计算长度
                    pRspADU->Pdu.ByteCount = dstDataLen;
                    dstBufLen = dstDataLen + 3;
                    crc = MB_GenerateCRC16CheckCode(pRspbuf, dstBufLen);
                    pRspADU->Pdu.Data[dstDataLen ] = (crc & 0xff00) >> 8;
                    pRspADU->Pdu.Data[dstDataLen + 1] = (crc & 0x00ff);
                   *pRspbuflen = dstBufLen + 2;
									 return MB_OK;
                 } else {
                    return MB_SLAVE_ExceptionRsp(hslave, pReqADU->Pdu.FunctionCode, 4, pRspbuf, pRspbuflen); 
                 }
        } else {
             return MB_SLAVE_ExceptionRsp(hslave, pReqADU->Pdu.FunctionCode, 2, pRspbuf, pRspbuflen);
        }

    } else {
        return MB_SLAVE_ExceptionRsp(hslave, pReqADU->Pdu.FunctionCode, 3, pRspbuf, pRspbuflen);
    }
}
